package com.example.ercmssystem2.config;

import com.example.ercmssystem2.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtConfig jwtConfig;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {

        final String authorizationHeader = request.getHeader(jwtConfig.getHeader());
        logger.debug("Authorization header: {}", authorizationHeader);

        String username = null;
        String jwt = null;

        // 只有Authorization头存在且格式正确时才处理
        if (authorizationHeader != null && authorizationHeader.startsWith(jwtConfig.getPrefix())) {
            jwt = authorizationHeader.substring(jwtConfig.getPrefix().length());
            logger.debug("Extracted JWT token: {}", jwt);
            
            // 验证JWT令牌格式
            if (jwt != null && !jwt.trim().isEmpty()) {
                try {
                    username = jwtUtil.extractUsername(jwt);
                    logger.debug("Extracted username from JWT: {}", username);
                } catch (Exception e) {
                    logger.warn("Failed to extract username from JWT token: {}", e.getMessage());
                    // Token无效，清除认证上下文并继续
                    SecurityContextHolder.clearContext();
                    filterChain.doFilter(request, response);
                    return;
                }
            }
        }

        // 只有当用户名存在且当前没有认证时才进行认证
        if (username != null && !username.trim().isEmpty() && SecurityContextHolder.getContext().getAuthentication() == null) {
            logger.debug("Attempting to load user details for username: {}", username);
            try {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                logger.debug("Successfully loaded user details for username: {}", username);

                // 严格验证JWT令牌
                if (jwtUtil.validateToken(jwt, userDetails)) {
                    logger.debug("JWT token is valid for user: {}", username);
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    logger.debug("Authentication set for user: {}", username);
                } else {
                    logger.warn("JWT token validation failed for user: {}", username);
                    // 令牌验证失败，清除认证上下文
                    SecurityContextHolder.clearContext();
                }
            } catch (Exception e) {
                logger.error("Failed to load user details for username: {} - Error: {}", username, e.getMessage());
                // 用户加载失败，清除认证上下文
                SecurityContextHolder.clearContext();
            }
        } else if (username == null && authorizationHeader != null) {
            // 有Authorization头但无法提取用户名，清除认证上下文
            logger.warn("Authorization header present but could not extract username");
            SecurityContextHolder.clearContext();
        }
        
        filterChain.doFilter(request, response);
    }
} 